home *** CD-ROM | disk | FTP | other *** search
/ QuickTime 2.0 Developer Kit / QuickTime 2.0 Developer Kit.iso / mac / MAC / Programming Stuff / Sample Code / Music Architecture / Embedding Instruments / BigEasy / BigEasy2.c next >
Encoding:
C/C++ Source or Header  |  1994-12-06  |  46.7 KB  |  2,377 lines  |  [TEXT/KAHL]

  1. /*
  2.     File:        BigEasy2.c
  3.  
  4.     Copyright:    © 1990-1992, 1994 by Apple Computer, Inc., all rights reserved.
  5.  
  6.     This file is used in these builds: Warhol
  7.  
  8.     Change History (most recent first):
  9.  
  10.         <40+>     17-8-94    dvb        allocate gx job when pagesetup, no sooner, coz its slow.
  11.         <40>     17-8-94    dvb        GX Printing
  12.         <39>      9-8-94    dvb        
  13.         <38>     27-7-94    dvb        installquititem
  14.         <37+>     5/27/94    dvb        InstallQuitItem
  15.         <37>     5/27/94    dvb        .
  16.         <35>      1/7/93    dvb        Compile under mpw.
  17.         <34>      1/6/93    dvb        Built in window-copy command.
  18.         <33>     4/23/92    dvb        Test checkout from new project
  19.         <32>     4/13/92    dvb        Pass activate/deactivates to back windows.
  20.         <31>     3/22/92    dvb        QuitApp message.
  21.         <30>     1/20/92    dvb        Cool new features. Much easier appleevents.
  22.         <29>    12/19/91    JB        removing think 4.0 code
  23.         <28>    10/14/91    JB        added #ifdef to create old window ports for debugging
  24.         <27>     9/18/91    PH        support silly disk inserted events
  25.         <26>     8/12/91    MD        support for timing profiler nastiness
  26.         <25>      7/3/91    PH        qd. is bad under old think
  27.         <24>     6/28/91    dvb        Make it work with/without MacHeaders in LSC5.
  28.         <23>      6/4/91    PH        compilin'
  29.         <22>      6/3/91    dvb        Just hackin.
  30.         <21>     5/28/91    JB        Added prototypes for BigEasy Proc Ptrs
  31.         <20>     5/27/91    PH        to compile again...
  32.         <19>     5/25/91    JB        OLD_THINK_C && TOOLBOX_LINKED
  33.         <18>     5/23/91    PH        changes for THINK 5
  34.         <17>     5/22/91    PH        new style prototypes
  35.         <16>      5/6/91    PH        nifty line after about...
  36.         <15>      5/5/91    dvb        Latest features, and App-Events for document open.
  37.        
  38.         <14>     4/25/91    JB        Changing to new THINK C interface files
  39.         <13>     4/19/91    PH        i like content clicks
  40.         <12>     4/19/91    dvb        Add WindowEventProc
  41.         <11>     3/29/91    PH        minor activate fix
  42.         <10>     3/29/91    dvb        Repair deactivate vs closewindow conflict, roll in latest cool
  43.                                     features.
  44.          <9>      3/9/91    dvb        Adjust to work with or without (LSC) mac headers
  45.          <8>      3/7/91    JB        Adjusting for using MacHeaders
  46.          <7>      3/1/91    dvb        Trivial new functions
  47.          <6>     2/24/91    dvb        Various cool new calls
  48.          <5>     2/18/91    dvb        Miscellaneous Updates
  49.          <4>      1/9/91    JB        Increasing ItemsPerMenu & #Menus
  50.          <3>    11/21/90    JB        Changes for INIT & mpw compatability
  51.          <2>    11/17/90    dvb        Pass on unused command-keys to document windows
  52.         <1>    11/17/90    dvb        New again after 1st CD pressing! Yay!
  53.  
  54.     To Do:
  55. */
  56.  
  57. /* file: BigEasy2.c
  58.   *
  59.   * Started 30 June 1988, more or less.
  60.   *
  61.   * A set of routines to allow the quick development
  62.   * of simple Macintosh applications.
  63.   * :)
  64.   */
  65.  
  66.  
  67. #define BigEasy2
  68.  
  69. #include <QuickDraw.h>
  70. #include <GestaltEqu.h>
  71. #include <Events.h>
  72. #include <AppleEvents.h>
  73. #include <Resources.h>
  74. #include <Menus.h>
  75. #include <ToolUtils.h>
  76. #include <Menus.h>
  77. #include <Windows.h>
  78. #include <Dialogs.h>
  79. #include <Memory.h>
  80. #include <Desk.h>
  81. #include <Fonts.h>
  82. #include <OSEvents.h>
  83. #include <Scrap.h>
  84. #include <SegLoad.h>
  85. #include <Resources.h>
  86.  
  87.  
  88. #ifdef BigEasyGXPrinting
  89.     #include <PrintingManager.h>
  90.     #include <Graphics Toolbox.h>
  91.     #include <Graphics Routines.h>
  92. #endif
  93.  
  94.  
  95.  
  96. /* #define THINK_C_PROFILE /* */
  97. #if defined(TIMING_PROFILE) || defined(STACK_KILLER)
  98.     #include "stack killer.h"
  99. #endif
  100.  
  101. #include "BigEasy2.h"
  102.  
  103.  
  104.  
  105. #ifdef BigEasyGXPrinting
  106.     #define WantsGX 1
  107. #else
  108.     #define WantsGX 0
  109. #endif
  110.  
  111. /*----------------
  112.     Limits
  113. ----------------*/
  114. #define kMMax 10            /* Number of menus in menubar */
  115. #define kMIMax 50            /* Number of items per menu */
  116. #define kMenuNameMax 32        /* Length of a menu title */
  117.  
  118. #define kStagLimX 97
  119. #define kStagLimY 37
  120.  
  121. /*----------------
  122.     Constants
  123. ----------------*/
  124. #define    kOSEvent                        app4Evt    /* event used by MultiFinder */
  125. #define    kSuspendResumeMessage            1        /* high byte of suspend/resume event message */
  126. #define    kResumeMask                    1        /* bit of message field for resume vs. suspend */
  127.  
  128. #define kWinPosType 'bewP'
  129. #define trapExitToShell 0xA9F4
  130.  
  131.  
  132.  
  133. /*----------------
  134.     Major BigEasy2 Structures
  135. ----------------*/
  136.  
  137. typedef struct TEasyWindow
  138.     {
  139.     Boolean wUsed;
  140.     long iNum;
  141.     long flags;
  142.     Boolean wGrowable;
  143.     beUpdateProcPtr wUpdateProc;
  144.     beClickProcPtr wClickProc;
  145.     beKeyProcPtr wKeyProc;
  146.     beGoAwayProcPtr wGoAwayProc;
  147.     beWNumCallProcPtr wZoomProc;
  148.     beActivateProcPtr wActivateProc;
  149.     beDeactivateProcPtr wDeactivateProc;
  150.     beIdleProcPtr wIdleProc;
  151.     beResizeProcPtr wResizeProc;
  152.     beGrowWindowProcPtr wGrowWindowProc;
  153.     beMoveWindowProcPtr wMoveWindowProc;
  154.     beEventProcPtr wEventProc;
  155.     WindowPtr wWindow;
  156. #ifdef BigEasyGXPrinting
  157.     gxJob job;
  158. #endif
  159.     } TEasyWindow;
  160.  
  161. typedef struct
  162.     {
  163.     short ref;
  164.     char mark;
  165.     char enable;
  166.     char cmdEquiv;
  167.     beMenuProcPtr proc;
  168.     } TEasyMenuItem;
  169.  
  170. /*----------------
  171.     Globals
  172. ----------------*/
  173. static short gIdleSeed;
  174. static Rect gResizeLim = {50,50,1000,1000};
  175. static TEasyWindow **gEasyWindowListH;            /* Handle to array of window objects    */
  176. static TEasyWindow *gEasyWindowList;            /* Pointer to array of window objects    */
  177. static short gEasyWindowListSize;                /* Number of window objects allocated    */
  178.  
  179. /*** Menus ***/
  180. static MenuHandle gMenuHandleList[kMMax];        /* MenuHandles indexed by MenuID's         */
  181. static short gMenuLength[kMMax];
  182. static char gMenuName[kMMax][kMenuNameMax];
  183. static TEasyMenuItem gMenu[kMMax][kMIMax];
  184. static short gMenuCount;                        /* How many menus defined */
  185. static short gCurrentMenu;                        /* the one to add to */
  186. static MenuHandle gMenuEdit;                    /* Which one is the edit menu? */
  187.  
  188. /*** Phantom Menu ***/
  189. static MenuHandle phantomMenuH = 0;
  190.  
  191. /*** About ***/
  192. static beAboutProcPtr gAboutProc;
  193. static char gAboutS0[256];
  194.  
  195. /*** Application Edit Commands ***/
  196. static beWNumCallProcPtr gAppUndoProc,gAppCutProc,gAppCopyProc,gAppPasteProc,gAppClearProc;
  197.  
  198. static beMenuProcPtr gAppPageSetupProc=0,gAppPrintProc=0;
  199.  
  200. /*** Global Status ***/
  201. static beOpenAppProcPtr gMasterOpenAppProc;
  202. static beOpenDocProcPtr gMasterOpenDocProc;
  203. static beQuitAppProcPtr gMasterQuitAppProc;
  204.  
  205. static beAboutProcPtr gMasterIdleProc;
  206. static short gStagX,gStagY;
  207. static WindowPtr gLastFrontIdle;
  208. static short gLastFrontWindowNumber;
  209. static short gSleep;
  210. static short gCoolDragState;
  211. static Point gCoolDragPoint;
  212. static short gCoolDragWindowNumber;
  213. static TEasyWindow *gCoolDragEW;
  214. static Boolean gInvalidMenuBar;
  215.  
  216. static void *gOldExitToShell;
  217.  
  218. PicHandle GetWindowPICT(TEasyWindow *thisEasyWindow);
  219.  
  220. /*----------------
  221.     Prototypes
  222. ----------------*/
  223. static void InitToolbox(void);
  224. static void CheckMenubar(void);
  225. static void EventLoop(void);
  226. static void InitBigEasy(void);
  227. static void ExitBigEasy(void);
  228. static void InstallMyExitToShell(void);
  229. static pascal void MyExitToShell(void);
  230. static void GetGrowRect(WindowPtr,Rect*);
  231. static void EnoughEasyWindows(short);
  232. static void FrontDAEdits(void);
  233. static TEasyWindow *GoodWNum(short);
  234. static Boolean CoolBigEasyCmdKeys(short key);
  235.  
  236. static void DoMyAbout(void);
  237. static void BEUndo(short);
  238. static void BECopy(short);
  239. static void BECut(short);
  240. static void BEPaste(short);
  241. static void BEClear(short);
  242. static void BENull(void);
  243. void BEPageSetup(short n, short menuItem, short menuRef);
  244. void BEPrint(short n, short menuItem, short menuRef);
  245.  
  246. static void MenuClick(Point p);
  247. static void DeleteIndexedMenuItem(short menu,short item);
  248. static Boolean DoKeyPress(long k);
  249. static void MenuPoint(long theclick);
  250. static void StartMenus(void);
  251. static short ScanWindowList(WindowPtr w);
  252. static void DoMouseClick(EventRecord *event);
  253. static void MyDrawGrowIcon(WindowPtr w);
  254.  
  255. static pascal OSErr BigEasyOpenAppThang(AppleEvent *theEvent, AppleEvent *reply,long refCon);
  256. static pascal OSErr BigEasyOpenDocThang(AppleEvent *theEvent, AppleEvent *reply,long refCon);
  257. static pascal OSErr BigEasyQuitAppThang(AppleEvent *theEvent, AppleEvent *reply,long refCon);
  258. static OSErr MissedAEParameters (AppleEvent *message);
  259.  
  260. Boolean ActivateWindow(WindowPtr w, Boolean activate);
  261.  
  262. #ifdef BigEasyGXPrinting
  263. void MakeSureWeHaveJob(TEasyWindow *thisWindow);
  264. #endif
  265.  
  266. void main(void);
  267.  
  268. /*----------------
  269.     Some useful routines
  270. ----------------*/
  271.  
  272. void InitToolbox(void)
  273.     {
  274.     InitGraf(&qd.thePort);
  275.     InitFonts();
  276.     FlushEvents(0xffff,0);
  277.     InitWindows();
  278.     InitMenus();
  279.     InitDialogs(0);
  280.     TEInit();
  281.     InitCursor();
  282.     }
  283.  
  284.  
  285. void GetGrowRect(WindowPtr w,Rect *r)
  286.     {
  287.     register Rect *gr;
  288.  
  289.     gr = r;
  290.     *gr = w->portRect;
  291.     gr->left = gr->right - 15;
  292.     gr->top = gr->bottom - 15;
  293.     }
  294.  
  295. void GoWatch(void)
  296.     {
  297.     SetCursor(*(Cursor**)GetCursor(4));
  298.     }
  299.  
  300. void GoArrow(void)
  301.     {
  302.     SetCursor(&qd.arrow);
  303.     }
  304.  
  305. void GoCursor(short c)
  306. /*
  307.   * Attempt to set to cursor ID c,
  308.   * but skip it if not there.
  309.   */
  310.     {
  311.     register Cursor **cur;
  312.  
  313.     cur = (Cursor **)GetCursor(c);
  314.     if(cur)
  315.         SetCursor(*cur);
  316.     }
  317.  
  318. static void EnoughEasyWindows(short n)
  319. /*
  320.   * If there are less than n window objects in the list,
  321.   * grow the handle appropriately.
  322.   */
  323.     {
  324.     short i;
  325.  
  326.     n++;
  327.     if(gEasyWindowListSize < n)
  328.         {
  329.         HUnlock((Handle)gEasyWindowListH);
  330.         SetHandleSize((Handle)gEasyWindowListH,sizeof(TEasyWindow) * (long)n);
  331.         HLock((Handle)gEasyWindowListH);
  332.         gEasyWindowList = *gEasyWindowListH;
  333.  
  334.         for(i = gEasyWindowListSize; i < n; i++)
  335.             gEasyWindowList[i].wUsed = 0;
  336.  
  337.         gEasyWindowListSize = n;
  338.         }
  339.     }
  340.  
  341. static TEasyWindow *GoodWNum(short n)
  342. /*
  343.   * return true if n is the number of an
  344.   * existing, used window.
  345.   */
  346.     {
  347.     register TEasyWindow *thisWindow;
  348.     if(n<0 || n>=gEasyWindowListSize)
  349.         return 0;
  350.     thisWindow = &gEasyWindowList[n];
  351.     if(thisWindow->wUsed)
  352.         return thisWindow;
  353.     else
  354.         return 0;
  355.     }
  356.  
  357.  
  358. static void FrontDAEdits(void)
  359. /*
  360.  * Check the front window. If it's a DA,
  361.  * enable all edit menu options.
  362.  */
  363.     {
  364.     WindowRecord *w;
  365.  
  366.     w = (WindowRecord*)FrontWindow();
  367.     if(w->windowKind < 0)                                    /* Any click in a DA window: */
  368.         EnDisEdits(1,1,1,1,1);                                /* enable edit menu. */
  369.     }
  370.  
  371.  
  372. void DoMyAbout(void)
  373.     {
  374.     DialogPtr d;
  375.     Handle h;
  376.     short hit;
  377.  
  378.     if(gAboutProc)
  379.         (*gAboutProc)();
  380.     else
  381.         {
  382.         h = GetResource('DLOG',1962);                            /* does it exist? */
  383.         if( (ResError()==0) && (h!=nil) )
  384.             {
  385.             ParamText((StringPtr)gAboutS0,0,0,0);
  386.             d = GetNewDialog(1962,0,(WindowPtr)-1);
  387.             ModalDialog(nil,&hit);
  388.             DisposDialog(d);
  389.             }
  390.         }
  391.     }
  392.  
  393. void SetMasterIdle(r)
  394.     beAboutProcPtr r;
  395.     {
  396.     gMasterIdleProc = r;
  397.     }
  398.  
  399. void SetWindowResizeProc(short n,beResizeProcPtr resizeProc)
  400. /*
  401.   * Sets the procedure which gets called when the window is resized
  402.   */
  403.     {
  404.     TEasyWindow *thisWindow;
  405.  
  406.     thisWindow = GoodWNum(n);
  407.     if(thisWindow)
  408.         thisWindow->wResizeProc = resizeProc;
  409.     }
  410.  
  411. void SetWindowGrowWindowProc(short n,beGrowWindowProcPtr growWindowProc)
  412. /*
  413.   * Sets the procedure which gets called when the window grows.
  414.   *   Allows alternate to GrowWindow.
  415.   */
  416.     {
  417.     TEasyWindow *thisWindow;
  418.  
  419.     thisWindow = GoodWNum(n);
  420.     if(thisWindow)
  421.         thisWindow->wGrowWindowProc = growWindowProc;
  422.     }
  423.  
  424. void SetWindowMoveProc(short n,beMoveWindowProcPtr moveWindowProc)
  425.     {
  426.     TEasyWindow *thisWindow;
  427.  
  428.     thisWindow = GoodWNum(n);
  429.     if(thisWindow)
  430.         thisWindow->wMoveWindowProc = moveWindowProc;
  431.     }
  432.  
  433.  
  434. void SetWindowZoomProc(short n,beWNumCallProcPtr zoomProc)
  435.     {
  436.     register TEasyWindow *thisWindow;
  437.  
  438.     thisWindow = GoodWNum(n);
  439.     if(thisWindow)
  440.         thisWindow->wZoomProc = zoomProc;
  441.     }
  442.  
  443. void SetWindowEventProc(short n,beEventProcPtr eventProc)
  444.     {
  445.     register TEasyWindow *thisWindow;
  446.  
  447.     thisWindow = GoodWNum(n);
  448.     if(thisWindow)
  449.         thisWindow->wEventProc = eventProc;
  450.     }
  451.  
  452. long GetWindowFlags(short n)
  453.     {
  454.     TEasyWindow *thisWindow;
  455.  
  456.     if(!(thisWindow = GoodWNum(n)))
  457.         return 0;
  458.  
  459.     return thisWindow->flags;
  460.     }
  461.  
  462. void SetWindowFlags(short n,long flags)
  463.     {
  464.     TEasyWindow *thisWindow;
  465.  
  466.     if(!(thisWindow = GoodWNum(n)))
  467.         return;
  468.  
  469.     thisWindow->flags = flags;
  470.     }
  471.  
  472. void SetAbout(StringPtr progName,StringPtr s0,beAboutProcPtr aboutProc)
  473. /*
  474.  * Sets the program's name in the about box, and
  475.  * sets the second string as ParamText 0 (^0)
  476.  * for the about dialog, 1962.
  477.  */
  478.     {
  479.     short i;
  480.     
  481.     SetItem(gMenuHandleList[1],1,(StringPtr)progName);
  482.  
  483.     for(i=0; i<256; i++)
  484.         gAboutS0[i] = *s0++;
  485.  
  486.     gAboutProc = aboutProc;
  487.     } 
  488.  
  489. /*----------------
  490.     Error Handling
  491. ----------------*/
  492.  
  493. void InstallMyExitToShell(void)
  494. /*
  495.   * Add my HatStrap call to
  496.   * the classic routine, "ExitToShell"
  497.   */
  498.     {
  499.     gOldExitToShell =  (void *) NGetTrapAddress(trapExitToShell, ToolTrap);
  500.     NSetTrapAddress((UniversalProcPtr) MyExitToShell, trapExitToShell, ToolTrap);
  501.     }
  502.  
  503. pascal void MyExitToShell(void)
  504. /*
  505.   * My exit routine, which does
  506.   * all the good cleanup.
  507.   */
  508.     {
  509.     Hatstrap();
  510.     NSetTrapAddress((UniversalProcPtr) gOldExitToShell, trapExitToShell, ToolTrap);
  511.     ExitToShell();
  512.     }    
  513.  
  514. void FailNil(long x)
  515. /*
  516.   * If x is zero, post an error
  517.   * alert and quit the program.
  518.   */
  519.     {
  520.     if(!x)
  521.         {
  522.         Alert(200,nil);
  523.         Debugger();
  524.         ExitToShell();
  525.         }
  526.     }
  527.  
  528. void FailOSErr(long x)
  529. /*
  530.   * If x isn't zero, post an error
  531.   * alert and quit the program.
  532.   */
  533.     {
  534.     if(x)
  535.         {
  536.         Debugger();
  537.         Alert(200,nil);
  538.         ExitToShell();
  539.         }
  540.     }
  541.  
  542. /*----------------
  543.     Some inherent methods
  544. ----------------*/
  545.  
  546. void BEUndo(short n)
  547.     {
  548.     if(!SystemEdit(0) && gAppUndoProc)
  549.         (*gAppUndoProc)(n);
  550.     }
  551.  
  552. void BECut(short n)
  553.     {
  554.     if(!SystemEdit(2) && gAppCutProc)
  555.         (*gAppCutProc)(n);
  556.     }
  557.  
  558. PicHandle GetWindowPICT(TEasyWindow *tew)
  559.     {
  560.     Rect visBounds;
  561.     beUpdateProcPtr fp;
  562.     PicHandle picH;
  563.  
  564.     SetPort(tew->wWindow);    /* Set port to window    */
  565.  
  566.     visBounds = qd.thePort->portRect;
  567.     InsetRect(&visBounds,-1,-1);
  568.     ForeColor(blackColor);
  569.     BackColor(whiteColor);
  570.     PenSize(1,1);
  571.  
  572.     picH = OpenPicture(&visBounds);
  573.     ClipRect(&visBounds);
  574.     FrameRect(&visBounds);
  575.  
  576.     fp = tew->wUpdateProc;
  577.     if(fp)
  578.         (*fp)(tew->iNum);                            /* Call drawing proc    */
  579.  
  580.     SetOrigin(0,0);
  581.  
  582.     ClosePicture();
  583.     ClipRect(&gBigRect);
  584.  
  585.     return picH;
  586.     }
  587.  
  588.  
  589. void BECopy(short n)
  590.     {
  591.     TEasyWindow *thisEasyWindow;
  592.  
  593.     if(!SystemEdit(3))
  594.         {
  595.         thisEasyWindow = GoodWNum(n);
  596.         if(thisEasyWindow->flags & wCopyDraw)
  597.             /*
  598.              * 
  599.              */
  600.             {
  601.             PicHandle picH;
  602.  
  603.             picH = GetWindowPICT(thisEasyWindow);
  604.  
  605.             HLock((Handle)picH);
  606.             ZeroScrap();
  607.             PutScrap(GetHandleSize((Handle)picH),'PICT',(Ptr)*picH);
  608.  
  609.             KillPicture(picH);
  610.             }
  611.         else if(gAppCopyProc)
  612.             (*gAppCopyProc)(n);
  613.         }
  614.     }
  615.  
  616. void BEPaste(short n)
  617.     {
  618.     if(!SystemEdit(4) && gAppPasteProc)
  619.         (*gAppPasteProc)(n);
  620.     }
  621.  
  622. void BEClear(short n)
  623.     {
  624.     if(!SystemEdit(5) && gAppClearProc)
  625.         (*gAppClearProc)(n);
  626.     }
  627.  
  628. void BENull(void){}
  629.  
  630.  
  631. void BEPageSetup(short n, short menuItem, short menuRef)
  632.     {
  633.     OSErr err;
  634.     long oldMenus;
  635.  
  636. #ifdef BigEasyGXPrinting
  637.     TEasyWindow *tew;
  638.     gxDialogResult result;
  639.     gxEditMenuRecord editMenuRec;
  640.  
  641.     tew = GoodWNum(n);
  642.     if(tew->flags & wPrintDraw)
  643.         {
  644.         oldMenus = DisableAllMenus();
  645.     
  646.         editMenuRec.editMenuID = 0;
  647.         editMenuRec.cutItem = 0; 
  648.         editMenuRec.copyItem = 0;
  649.         editMenuRec.pasteItem = 0;
  650.         editMenuRec.clearItem = 0;
  651.         editMenuRec.undoItem = 0;
  652.         
  653.         MakeSureWeHaveJob(tew);
  654.         result = GXJobDefaultFormatDialog(tew->job,&editMenuRec);
  655.         err = GXGetJobError(tew->job);
  656.     
  657.         EnableAllMenus(oldMenus);
  658.         }
  659.     else
  660. #endif
  661.         {
  662.         if(gAppPageSetupProc)
  663.             (*gAppPageSetupProc)(n,menuItem,menuRef);
  664.         }
  665.     }
  666.  
  667. void BEPrint(short n, short menuItem, short menuRef)
  668.     {
  669.     OSErr err;
  670.     PicHandle picH;
  671.     Rect pictR,centeredR,pageR;
  672.     Point p;
  673.     Str255 s;
  674.     long oldMenus;
  675.  
  676. #ifdef BigEasyGXPrinting
  677.     TEasyWindow *tew;
  678.     gxFormat format;
  679.     gxTranslationStatistic stats;
  680.     gxRectangle pageSize,paperSize;
  681.     gxDialogResult result;
  682.     gxEditMenuRecord editMenuRec;
  683.     gxShape sh;
  684.  
  685.     tew = GoodWNum(n);
  686.     if(tew->flags & wPrintDraw)
  687.         {
  688.         oldMenus = DisableAllMenus();
  689.     
  690.         editMenuRec.editMenuID = 0;
  691.         editMenuRec.cutItem = 0; 
  692.         editMenuRec.copyItem = 0;
  693.         editMenuRec.pasteItem = 0;
  694.         editMenuRec.clearItem = 0;
  695.         editMenuRec.undoItem = 0;
  696.         
  697.         MakeSureWeHaveJob(tew);
  698.         result = GXJobPrintDialog(tew->job,&editMenuRec);
  699.         err = GXGetJobError(tew->job);
  700.     
  701.         picH = GetWindowPICT(tew);
  702.     
  703.         pictR = (**picH).picFrame;
  704.         p.h = p.v = 0;
  705.  
  706.         /*
  707.           * Center the image in the page rectangle
  708.           */
  709.         format = GXGetJobFormat(tew->job,1);
  710.         GXGetFormatDimensions(format,&pageSize,&paperSize);
  711.         pageR.top = pageSize.top >> 16;
  712.         pageR.bottom = pageSize.bottom >> 16;
  713.         pageR.left = pageSize.left >> 16;
  714.         pageR.right = pageSize.right >> 16;
  715.         centeredR = pictR;
  716.         OffsetRect(¢eredR,
  717.                 (pageR.left + pageR.right - pictR.left - pictR.right + 1) >> 1,
  718.                 (pageR.top + pageR.bottom - pictR.top - pictR.bottom + 1) >> 1);
  719.     
  720.         sh = GXConvertPICTToShape(picH, gxDefaultOptionsTranslation, &pictR, ¢eredR, p, nil, &stats);
  721.     
  722.         GetWTitle(tew->wWindow,s);
  723.     
  724.         GXStartJob(tew->job,s,0);
  725.         err = GXGetJobError(tew->job);
  726.         GXPrintPage(tew->job,1,nil,sh);
  727.         err = GXGetJobError(tew->job);
  728.         GXFinishJob(tew->job);
  729.         err = GXGetJobError(tew->job);
  730.         GXDisposeShape(sh);
  731.     
  732.         EnableAllMenus(oldMenus);
  733.         }
  734. #endif
  735.         {
  736.         if(gAppPageSetupProc)
  737.             (*gAppPageSetupProc)(n,menuItem,menuRef);
  738.         }
  739.     }
  740.  
  741.  
  742. /*----------------
  743.     Menu Action Routines
  744. ----------------*/
  745.  
  746. Boolean DoKeyPress(long k)
  747.     {
  748.     register long thePoint;
  749.     register Boolean didIt;
  750.  
  751.     thePoint = MenuKey((char)k);
  752.     didIt = (thePoint>>16) != 0;
  753.     if(didIt)
  754.         MenuPoint(thePoint);
  755.  
  756.     return didIt;
  757.     }
  758.     
  759. void MenuClick(Point p)
  760.     {
  761.     KeyMap     theKeys;
  762.     Boolean    putBack = false;
  763.     short    oldID;
  764.     
  765.     if (phantomMenuH) {
  766.     GetKeys(theKeys);
  767.         
  768.         if ((theKeys[1]&4) == 0) {
  769.             putBack = true;
  770.             oldID = (**phantomMenuH).menuID;
  771.             DeleteMenu( oldID );
  772.             }
  773.         }
  774.     MenuPoint(MenuSelect(p));
  775.     if (putBack)
  776.         {
  777.         InsertMenu(phantomMenuH,oldID);
  778.         }
  779.     }
  780.  
  781. void MenuPoint(long theclick)
  782.     {
  783.     register short mID,mItem;
  784.     char DAname[30];
  785.     short wNum;
  786.     TEasyWindow *thisWindow;
  787.     register beMenuProcPtr aProc;
  788.     register TEasyMenuItem *emi;
  789.  
  790.     mID = theclick>>16;
  791.     mItem = theclick & 0xffff;
  792.  
  793.     if(mID == 0) return;
  794.  
  795.     if(mID == 1)                            /* Apple menu */
  796.         {
  797.         if(mItem == 1)                        /* Its either the about box */
  798.             DoMyAbout();
  799.         else    
  800.             {                                    /* Or a DA */
  801.             GetItem(gMenuHandleList[1],mItem,(StringPtr)DAname);
  802.             OpenDeskAcc((StringPtr)DAname);
  803.             }
  804.         }
  805.     else
  806.         {
  807.         wNum = gLastFrontWindowNumber;
  808.         thisWindow = GoodWNum(wNum);
  809.         if(thisWindow)                                    /* if one of our window in front, setport    */
  810.             SetPort(thisWindow->wWindow);
  811.  
  812.         emi = &gMenu[mID][0];
  813.         aProc = emi->proc;
  814.         if(aProc)                                        /* call the menu's routine, if any        */
  815.             (*aProc)(wNum,mItem,gMenu[mID][mItem].ref);
  816.  
  817.         emi = &gMenu[mID][mItem];
  818.         aProc = emi->proc;
  819.         if(aProc)                                        /* call the item's routine, if any        */
  820.             (*aProc)(wNum,mItem,emi->ref);
  821.         }
  822.  
  823.     HiliteMenu(0);
  824.     }
  825.  
  826. char dAbout[] = "\pAbout ";
  827.  
  828. void StartMenus(void)
  829. /*
  830.  * Start with just an About box, and some DA's.
  831.  */
  832.     {
  833.     char aboutS[255];
  834.     MenuHandle applemenu;
  835.  
  836.     BlockMove(&dAbout[0],aboutS,dAbout[0]+1);            /* "About" */
  837.     BlockMove((StringPtr )0x910 + 1,aboutS + aboutS[0] + 1, *(StringPtr )0x910); /* ProgName */
  838.     aboutS[0] += *((StringPtr )0x910);
  839.     aboutS[aboutS[0] + 1] = '…';
  840.     aboutS[0]++;
  841.  
  842.     applemenu = NewMenu(1,(StringPtr)"\p");                /* Apple menu: ID 1                    */
  843.     AppendMenu(applemenu,(StringPtr)aboutS);
  844.     AppendMenu(applemenu,(StringPtr)"\p(-");
  845.     AddResMenu(applemenu,'DRVR');
  846.     InsertMenu(applemenu,0);
  847.     DrawMenuBar();
  848.     gMenuHandleList[1] = applemenu;
  849.     gMenu[1][0].enable = true;
  850.  
  851.     gMenuCount = 1;                        /* Next menu added will be ID 2        */
  852.     gCurrentMenu = 1;
  853.     gMenuLength[1] = 0;                    /* No items, really, in Apple menu        */
  854.     }
  855.  
  856. MenuHandle InstallMenu(StringPtr s,beMenuProcPtr action,short ref)
  857. /*
  858.  * Start a new menu with name s
  859.  */
  860.     {
  861.     register TEasyMenuItem *emi;
  862.     register MenuHandle mh;
  863.  
  864.     gMenuCount++;                                /* new menu                        */
  865.     gCurrentMenu = gMenuCount;
  866.  
  867.     if(*s > kMenuNameMax-1)
  868.         *s = kMenuNameMax-1;
  869.  
  870.     gMenuLength[gCurrentMenu] = 0;
  871.     mh = NewMenu(gCurrentMenu,(StringPtr)s);
  872.     gMenuHandleList[gCurrentMenu] = mh;
  873.     InsertMenu(mh,0);
  874.  
  875.     emi = &gMenu[gCurrentMenu][0];
  876.     emi->enable = ref >= 0;
  877.     if(!emi->enable)
  878.         {
  879.         DisableItem(mh,0);
  880.         ref =- ref;
  881.         }
  882.     emi->proc = action;
  883.     emi->ref = ref;
  884.  
  885.     gInvalidMenuBar = true;                    /* redraw soon */
  886.     BlockMove(s,gMenuName[gCurrentMenu],*s+1);
  887.     return mh;
  888.     }
  889.  
  890. static Str255 dQuitString = "\pQuit ";
  891. #define kQuitLength 5
  892. static Str15 dQuitCmdKey = "\p/Q";
  893.  
  894. void InstallQuitItem(beMenuProcPtr action,short ref)
  895.     {
  896.     short i,j;
  897.     StringPtr w;
  898.  
  899.     i = kQuitLength;
  900.  
  901.     w = (StringPtr)0x910;
  902.     j = *w++;
  903.     while(j--)
  904.         dQuitString[++i] = *w++;
  905.  
  906.     w = dQuitCmdKey;
  907.     j = *w++;
  908.     while(j--)
  909.         dQuitString[++i] = *w++;
  910.  
  911.     dQuitString[0] = i;
  912.  
  913.     InstallMenuItem(dQuitString,action,ref);
  914.     }
  915.  
  916.  
  917.  
  918. void InstallMenuItem(StringPtr s,beMenuProcPtr action,short ref)
  919. /*
  920.  * Add an item to the last menu, and associate a routine with it.
  921.  */
  922.     {
  923.     register MenuHandle mh;
  924.     register TEasyMenuItem *emi;
  925.     register short item;
  926.  
  927.  
  928.     mh = gMenuHandleList[gCurrentMenu];
  929.     gMenuLength[gCurrentMenu]++;
  930.     item = gMenuLength[gCurrentMenu];
  931.     emi = &gMenu[gCurrentMenu][item];
  932.  
  933.     if (ref < 0)
  934.         {
  935.         DisableItem(mh,item);
  936.         ref =- ref;
  937.         emi->enable = 0;
  938.         }
  939.     else
  940.         emi->enable = 1;
  941.  
  942.     AppendMenu(mh,(StringPtr)s);
  943.     emi->proc = action;
  944.     emi->ref = ref;
  945.     emi->mark = 0;
  946.     if(*(s+*s-1) == '/')
  947.         emi->cmdEquiv = *(s+*s);
  948.     else
  949.         emi->cmdEquiv = 0;
  950.     }
  951.  
  952. void RemoveMenuItem(short ref)
  953. /*
  954.  * Remove all menu items with
  955.  * refcon ref.
  956.  */
  957.     {
  958.     short menu;
  959.     short item;
  960.  
  961.     for(menu = 1; menu <= gMenuCount; menu++)
  962.         for(item = gMenuLength[menu]; item > 0; item--)
  963.             {
  964.             if(gMenu[menu][item].ref == ref)
  965.                 DeleteIndexedMenuItem(menu,item);
  966.             }
  967.     }
  968.  
  969. void DeleteIndexedMenuItem(short menu,short item)
  970.     {
  971.     StringPtr oldStrings;
  972.     MenuHandle mh;
  973.     short i;
  974.     short itemCount;
  975.     register TEasyMenuItem *emi;
  976.     register StringPtr w;
  977.  
  978.     itemCount = gMenuLength[menu];
  979.     mh = gMenuHandleList[menu];
  980.     oldStrings = (StringPtr)NewPtrClear(256 * (itemCount));
  981.     FailNil((long)oldStrings);
  982.  
  983.     for(i = 1; i<=itemCount; i++)
  984.         GetItem(mh,i,(StringPtr)&oldStrings[(i-1)*256]);
  985.  
  986.     DeleteMenu(menu);
  987.     DisposeMenu(mh);
  988.  
  989.     mh = NewMenu(menu,(StringPtr)gMenuName[menu]);
  990.     emi = &gMenu[menu][1];
  991.     w = oldStrings;
  992.     for(i = 1; i<=itemCount; i++)
  993.         {
  994.         if(i != item)
  995.             {
  996.             if(emi->cmdEquiv)
  997.                 {
  998.                 *(w+*w+1) = '/';
  999.                 *(w+*w+2) = emi->cmdEquiv;
  1000.                 *w = *w + 2;
  1001.                 }
  1002.             AppendMenu(mh,(StringPtr)w);
  1003.             }
  1004.         emi++;
  1005.         w += 256;
  1006.         }
  1007.  
  1008.     emi = &gMenu[menu][item];
  1009.     for(i = item; i<itemCount; i++)
  1010.         {
  1011.         *emi = *(emi+1);
  1012.         emi++;
  1013.         }
  1014.  
  1015.     gMenuLength[menu]--;
  1016.     itemCount--;
  1017.  
  1018.     emi = &gMenu[menu][1];
  1019.     for(i = 1; i<=itemCount; i++)
  1020.         {
  1021.         if(!emi->enable)
  1022.             DisableItem(mh,i);
  1023.         if(emi->mark)
  1024.             SetItemMark(mh,i,emi->mark);
  1025.         emi++;
  1026.         }
  1027.  
  1028.     InsertMenu(mh,menu+1);
  1029.     DisposPtr((Ptr)oldStrings);
  1030.     }
  1031.  
  1032. void InstallEditMenu(beWNumCallProcPtr Xundo,
  1033.         beWNumCallProcPtr Xcut,
  1034.         beWNumCallProcPtr Xcopy,
  1035.         beWNumCallProcPtr Xpaste,
  1036.         beWNumCallProcPtr Xclear)
  1037.     /*
  1038.      * Start an edit menu, and put the first six things in.
  1039.      */
  1040.     {
  1041.     gAppUndoProc = Xundo;
  1042.     gAppCutProc = Xcut;
  1043.     gAppCopyProc = Xcopy;
  1044.     gAppPasteProc = Xpaste;
  1045.     gAppClearProc = Xclear;
  1046.  
  1047.     InstallMenu("\pEdit",nil,0);
  1048.     InstallMenuItem("\px/Z",(beMenuProcPtr)BEUndo,-mUndo);            /* barfs because it is static */
  1049.     InstallMenuItem("\p(-",(beMenuProcPtr)BENull,0);
  1050.     InstallMenuItem("\px/X",(beMenuProcPtr)BECut,-mCut);
  1051.     InstallMenuItem("\px/C",(beMenuProcPtr)BECopy,-mCopy);
  1052.     InstallMenuItem("\px/V",(beMenuProcPtr)BEPaste,-mPaste);
  1053.     InstallMenuItem("\px/B",(beMenuProcPtr)BEClear,-mClear);
  1054.  
  1055.     gMenuEdit = gMenuHandleList[gCurrentMenu];
  1056.  
  1057.     EnDisEdits(-1,-1,-1,-1,-1);
  1058.     }
  1059.  
  1060. void InstallPrintItems(beMenuProcPtr pageSetup,beMenuProcPtr print)
  1061.     {
  1062.     gAppPageSetupProc = pageSetup;
  1063.     gAppPrintProc = print;
  1064.  
  1065.     InstallMenuItem("\pPage Setup…/π",(beMenuProcPtr)BEPageSetup,-mPageSetup);
  1066.     InstallMenuItem("\pPrint…/P",(beMenuProcPtr)BEPrint,-mPrint);
  1067.     }
  1068.  
  1069. void SetMenuItem(short ref,char enable,char isMarked,char mark,StringPtr s)
  1070. /*
  1071.   * Set all items with the reference number to the
  1072.   * enable/disable state, with mark, and name s.
  1073.   * pass enable + to enable, - to disable, and
  1074.   * zero to leave alone.
  1075.   */
  1076.     {
  1077.     short m,i;
  1078.     MenuHandle mh;
  1079.     register TEasyMenuItem *emi;
  1080.  
  1081.     for(m=1; m<=gMenuCount; m++)
  1082.         {
  1083.         mh = gMenuHandleList[m];
  1084.         for(i=gMenuLength[m]; i>=0; i--)
  1085.             {
  1086.             emi = &gMenu[m][i];
  1087.             if(emi->ref == ref)
  1088.                 {
  1089.                 if(enable)
  1090.                     {
  1091.                     if(!i)
  1092.                         gInvalidMenuBar = true;
  1093.                     if(enable > 0)
  1094.                         {
  1095.                         emi->enable = 1;
  1096.                         EnableItem(mh,i);
  1097.                         }
  1098.                     else
  1099.                         {
  1100.                         emi->enable = 0;
  1101.                         DisableItem(mh,i);
  1102.                         }
  1103.                     }
  1104.                 if(i > 0)                    /* these only apply to items */
  1105.                     {
  1106.                     if(isMarked)
  1107.                         if(isMarked > 0)
  1108.                             {
  1109.                             emi->mark = mark;
  1110.                             SetItemMark(mh,i,mark);
  1111.                             //CheckItem(mh,i,true);
  1112.                             }
  1113.                         else
  1114.                             {
  1115.                             emi->mark = 0;
  1116.                             SetItemMark(mh,i,0);
  1117.                             }
  1118.                     if(s)
  1119.                         SetItem(mh,i,(StringPtr)s);
  1120.                     }
  1121.                 }
  1122.             }
  1123.         }
  1124.     }
  1125.  
  1126.  
  1127.  
  1128. void EnDisEdits(short Eundo,short Ecut,short Ecopy,short Epaste,short Eclear)
  1129. /*
  1130.  * For each edit menu entry,
  1131.  * -1=disable, 1=enable, 0=leave alone.
  1132.  */
  1133.     {
  1134.     SetMenuItem(mUndo,Eundo,false,0,"\pUndo");
  1135.     SetMenuItem(mCut,Ecut,false,0,"\pCut");
  1136.     SetMenuItem(mCopy,Ecopy,false,0,"\pCopy");
  1137.     SetMenuItem(mPaste,Epaste,false,0,"\pPaste");
  1138.     SetMenuItem(mClear,Eclear,false,0,"\pClear");
  1139.     }
  1140.  
  1141. MenuHandle SetCurrentMenu(short ref)
  1142. /*
  1143.  * Set which menu will take
  1144.  * future "InstallMenuItem"s.
  1145.  */
  1146.     {
  1147.     register short i;
  1148.  
  1149.     for(i = 0; i<gMenuCount; i++)
  1150.         {
  1151.         if(gMenu[i][0].ref == ref)
  1152.             {
  1153.             gCurrentMenu = i;
  1154.             return gMenuHandleList[i];
  1155.             }
  1156.         }
  1157.     return 0;
  1158.     }
  1159.  
  1160. long DisableAllMenus(void)
  1161. /*
  1162.  * Disable all menus, as for a modal dialog,
  1163.  * and return a long with the masks of which should get reenabled.
  1164.  */
  1165.     {
  1166.     long result;
  1167.     long mask;
  1168.     TEasyMenuItem *emi;
  1169.     short i;
  1170.  
  1171.     result = 0;
  1172.     mask = 1;
  1173.     for(i = 0; i<kMMax; i++)
  1174.         {
  1175.         emi = &gMenu[i][0];
  1176.         if(emi->enable)
  1177.             {
  1178.             DisableItem(gMenuHandleList[i],0);
  1179.             result |= mask;
  1180.             }
  1181.         mask <<= 1;
  1182.         }
  1183.     DrawMenuBar();
  1184.     return result;
  1185.     }
  1186.  
  1187. void EnableAllMenus(long saveMenus)
  1188. /*
  1189.  * Enable menus according to the mask returned by DisableAllMenus().
  1190.  */
  1191.     {
  1192.     long mask;
  1193.     short i;
  1194.  
  1195.     mask = 1;
  1196.     for(i = 0; i<kMMax; i++)
  1197.         {
  1198.         if(saveMenus & mask)
  1199.             EnableItem(gMenuHandleList[i],0);
  1200.         mask <<= 1;
  1201.         }
  1202.     DrawMenuBar();
  1203.     }
  1204.  
  1205.  
  1206. short ScanWindowList(WindowPtr w)
  1207. /*
  1208.   * return a window number from a WindowPeek,
  1209.   * or -1 if no known window.
  1210.   */
  1211.     {
  1212.     short i;
  1213.     TEasyWindow *wo;
  1214.  
  1215.     wo= &gEasyWindowList[0];
  1216.  
  1217.     for(i=0; i<gEasyWindowListSize; i++)
  1218.         {
  1219.         if (wo->wUsed && (wo->wWindow==w))
  1220.             return i;
  1221.         wo++;
  1222.         }
  1223.     return -1;
  1224.     }
  1225.  
  1226.  
  1227. /*----------------
  1228.     Mouse Action Routines
  1229. ----------------*/
  1230. void DoMouseClick(EventRecord *event)
  1231.     {
  1232.     WindowPtr w;
  1233.     short part;
  1234.     register short wNum;
  1235.     register TEasyWindow *thisEasyWindow;
  1236.     Point p;
  1237.     Rect r;
  1238.     Boolean tookEvent;
  1239.  
  1240.     p = event->where;
  1241.     part = FindWindow (p, &w);
  1242.     wNum = ScanWindowList(w);
  1243.     thisEasyWindow = GoodWNum(wNum);
  1244.  
  1245.     switch (part)
  1246.         {
  1247.         case inDesk:
  1248.             break;
  1249.  
  1250.         case inMenuBar:
  1251.             MenuClick(p);
  1252.             break;
  1253.         
  1254.         case inSysWindow:
  1255.             SystemClick(event,w);
  1256.             break;
  1257.         
  1258.         case inContent:
  1259.         contentClick:
  1260.             if (w != FrontWindow())                /* If clicked on a non-front window, */
  1261.                 SelectWindow(w);                            /* bring it to the front. */
  1262.             else if(thisEasyWindow)                            /* Click on front window: give click */
  1263.                 {                                        /* to window's click routine. */
  1264.                 SetPort(w);
  1265.                 GlobalToLocal(&p);
  1266.  
  1267.                 ClipRect(&gBigRect);
  1268.                 SetOrigin(0,0);
  1269.  
  1270.                 if(thisEasyWindow && thisEasyWindow->wEventProc)
  1271.                     (*thisEasyWindow->wEventProc)(wNum,event,&tookEvent);
  1272.                 else
  1273.                     tookEvent = false;
  1274.  
  1275.                 if(!tookEvent)
  1276.                     {
  1277.                     register beClickProcPtr fp;
  1278.  
  1279.                     fp = thisEasyWindow->wClickProc;
  1280.                     if(fp)
  1281.                         (*fp)(wNum,p,
  1282.                                 event->modifiers);
  1283.                     }
  1284.                 }
  1285.             break;
  1286.  
  1287.         case inDrag:
  1288.             if(((thisEasyWindow->flags & wCoolDrag)!=0)
  1289.                     ^ ((event->modifiers & optionKey)!=0))
  1290.                 {
  1291.                 gCoolDragPoint = event->where;
  1292.                 gCoolDragState = 1;
  1293.                 gCoolDragEW = thisEasyWindow;
  1294.                 gCoolDragWindowNumber = wNum;
  1295.                 if(!(event->modifiers & 256))
  1296.                     SelectWindow(w);
  1297.                 }
  1298.             else
  1299.                 if(Button())                                /* for quick title-bar clicks */
  1300.                     {
  1301.                     beMoveWindowProcPtr fp;
  1302.  
  1303.                     DragWindow(w,event->where,&gBigRect);
  1304.                     fp = thisEasyWindow->wMoveWindowProc;
  1305.                     if(fp)
  1306.                         (fp)(wNum);                    
  1307.                     }
  1308.                 else
  1309.                     SelectWindow(w);
  1310.             break;
  1311.  
  1312.         case inGrow:
  1313.             if(thisEasyWindow && (thisEasyWindow->flags & wGrowable))
  1314.                 {
  1315.                 long oldSize,newSize;
  1316.                 beGrowWindowProcPtr fp;
  1317.                 beResizeProcPtr rsfp;
  1318.                 
  1319.                 SetPort(w);
  1320.                 GetGrowRect(w,&r);
  1321.                 InvalRect(&r);
  1322.  
  1323.                 fp = thisEasyWindow->wGrowWindowProc;
  1324.                 if(fp)
  1325.                     (*fp)(&newSize,wNum,w,event->where,&gResizeLim);
  1326.                 else
  1327.                     newSize = GrowWindow(w,event->where,&gResizeLim);
  1328.  
  1329.                 rsfp = thisEasyWindow->wResizeProc;
  1330.                 if(rsfp)
  1331.                     {
  1332.                     oldSize = ((long)(w->portRect.bottom-w->portRect.top)<<16) |
  1333.                             (w->portRect.right-w->portRect.left);
  1334.                     (*rsfp)(wNum,(Point *)&oldSize,(Point *)&newSize,event->modifiers);
  1335.                     }
  1336.                 else
  1337.                     SizeWindow(w,newSize&0xffff,newSize>>16,1);
  1338.  
  1339.                 GetGrowRect(w,&r);
  1340.                 InvalRect(&r);
  1341.                 }
  1342.             else
  1343.                 goto contentClick;
  1344.             break;
  1345.  
  1346.         case inGoAway:
  1347.             if(thisEasyWindow)
  1348.                 if (TrackGoAway(w,event->where))
  1349.                     {
  1350.                     beGoAwayProcPtr fp;
  1351.                     
  1352.                     fp = thisEasyWindow->wGoAwayProc;
  1353.                     if(fp)
  1354.                         (*fp)(wNum);
  1355.                     }
  1356.             break;
  1357.  
  1358.         /*
  1359.          * The following way to handle zoom only
  1360.          * applies to zooming to 1 state.  This does
  1361.          * not handle zooming in and out between 2
  1362.          * states.  Check IM IV.
  1363.          */
  1364.  
  1365.         case inZoomIn:    /* zoomBox */
  1366.         case inZoomOut:
  1367.             if(thisEasyWindow)
  1368.                 {
  1369.                 if (TrackBox(w,event->where,part))
  1370.                     {
  1371.                     beWNumCallProcPtr fp;
  1372.                     
  1373.                     fp = thisEasyWindow->wZoomProc;
  1374.                     if(fp)
  1375.                         (*fp)(wNum);
  1376.                     }
  1377.                 }
  1378.             break;
  1379.         }
  1380.     }
  1381.  
  1382. /*----------------
  1383.     Window Action Routines
  1384. ----------------*/
  1385.  
  1386. WindowPtr InstallWindow(short iNum,StringPtr iTitle,Rect *iRect,short iType,short iFlags,
  1387.         beUpdateProcPtr iUpdate,beClickProcPtr iClick,beKeyProcPtr iKey,beGoAwayProcPtr iGoAway,
  1388.         beActivateProcPtr iActivate,beDeactivateProcPtr iDeactivate,beIdleProcPtr iIdle)
  1389. /*
  1390.  * Add a window to BigEasy's list. If the window is
  1391.  * already up somewhere, bring it to the front and
  1392.  * visualize it.
  1393.  */
  1394.     {
  1395.     TEasyWindow *thisWindow;
  1396.     Rect stagRect,**oldPos;
  1397.     Boolean isVisible;
  1398.     RgnHandle rh;
  1399.     KeyMap km;
  1400.     Boolean opt;
  1401.  
  1402.     GetKeys(km);
  1403.  
  1404.     opt =km[58/8] &  (1<< (58%8) );
  1405.  
  1406.     isVisible = iNum>0;
  1407.     if(!isVisible)
  1408.         iNum = -iNum;
  1409.  
  1410.     EnoughEasyWindows(iNum);            /* Make sure there's space for new one        */
  1411.     thisWindow = &gEasyWindowList[iNum];
  1412.  
  1413.     if (thisWindow->wUsed)                /* something already assigned to this window? */
  1414.         {
  1415.         Show(iNum);
  1416.         goto goHome;
  1417.         }
  1418.  
  1419.     oldPos = (Rect **)Get1Resource(kWinPosType,iNum);    /* attempt to find saved window position        */
  1420.     stagRect = *iRect;
  1421.  
  1422.     if(oldPos && !opt)                                    /* (option key "forgets" old window */
  1423.         OffsetRect(&stagRect,
  1424.                 (**oldPos).left - stagRect.left,(**oldPos).top - stagRect.top);
  1425.  
  1426.         {
  1427.         Rect lilRect;
  1428.  
  1429.         lilRect.top = stagRect.top - 10;
  1430.         lilRect.left = stagRect.left + 4;
  1431.         lilRect.bottom = lilRect.top + 1;
  1432.         lilRect.right = lilRect.left + 1;
  1433.  
  1434.         rh = NewRgn();
  1435.         RectRgn(rh,&lilRect);
  1436.         SectRgn(rh,*(RgnHandle *)0x9EE,rh);
  1437.         if(EmptyRgn(rh) && gWindowsInView)
  1438.             OffsetRect(&stagRect,50 - iRect->left,80 - iRect->top);
  1439.  
  1440.         if(gStaggerWindows)
  1441.             {
  1442.             gStagX = (gStagX + gStagStepX)%kStagLimX;
  1443.             gStagY = (gStagY + gStagStepY)%kStagLimY;
  1444.             OffsetRect(&stagRect,gStagX,gStagY);
  1445.             }
  1446.         DisposeRgn(rh);
  1447.         }
  1448.  
  1449.     thisWindow->wUsed = 1;
  1450.  
  1451.     if(gHasColor)
  1452.         thisWindow->wWindow = NewCWindow(0,&stagRect,(StringPtr)iTitle,isVisible,
  1453.                 ((iFlags & wZoomable) != 0) ? zoomDocProc : iType,
  1454.                 (WindowPtr)-1,iGoAway!=0,0);
  1455.     else
  1456.         thisWindow->wWindow = NewWindow(0,&stagRect,(StringPtr)iTitle,isVisible,
  1457.                 ((iFlags & wZoomable) != 0) ? zoomDocProc : iType,
  1458.                 (WindowPtr)-1,iGoAway!=0,0);
  1459.  
  1460.     SetPort(thisWindow->wWindow);
  1461.  
  1462.     thisWindow->flags = iFlags;
  1463.     thisWindow->iNum = iNum < 0 ? -iNum : iNum;
  1464.     thisWindow->wUpdateProc = iUpdate;
  1465.     thisWindow->wClickProc = iClick;
  1466.     thisWindow->wKeyProc = iKey;
  1467.     thisWindow->wGoAwayProc = iGoAway;
  1468.     thisWindow->wZoomProc = nil;
  1469.     thisWindow->wActivateProc = iActivate;
  1470.     thisWindow->wDeactivateProc = iDeactivate;
  1471.     thisWindow->wIdleProc = iIdle;
  1472.     thisWindow->wResizeProc = nil;
  1473.     thisWindow->wGrowWindowProc = nil;
  1474.     thisWindow->wMoveWindowProc = nil;
  1475.     thisWindow->wEventProc = nil;
  1476.  
  1477. #ifdef BigEasyGXPrinting
  1478.     thisWindow->job = nil;
  1479. #endif
  1480.  
  1481. goHome:
  1482.     return thisWindow->wWindow;
  1483.     }
  1484.  
  1485.  
  1486. #ifdef BigEasyGXPrinting
  1487. void MakeSureWeHaveJob(TEasyWindow *thisWindow)
  1488.     {
  1489.     if(!thisWindow->job)
  1490.         if((thisWindow->flags & wPrintDraw) && gHasGX)
  1491.             {
  1492.             GoWatch();
  1493.             GXNewJob(&thisWindow->job);
  1494.             GoArrow();
  1495.             }
  1496.     }
  1497. #endif
  1498.  
  1499.  
  1500.  
  1501.  
  1502. void UninstallWindow(short iNum)
  1503.     {
  1504.     register TEasyWindow *thisWindow;
  1505.     register beDeactivateProcPtr fp;
  1506.  
  1507.     gCoolDragState = 0;                    /* just in case we were dragging the dissappeared window */
  1508.  
  1509.     if(!(thisWindow = GoodWNum(iNum)))
  1510.         return;
  1511.  
  1512.     SetPort(thisWindow->wWindow);
  1513.  
  1514.     fp = thisWindow->wDeactivateProc;
  1515.     if(fp)
  1516.         (*fp)(iNum);
  1517.     CloseWindow(thisWindow->wWindow);
  1518.     EnDisEdits(-1,-1,-1,-1,-1);
  1519.  
  1520. #ifdef BigEasyGXPrinting
  1521.     if((thisWindow->flags & wPrintDraw) && gHasGX)
  1522.         GXDisposeJob(thisWindow->job);
  1523. #endif
  1524.  
  1525.     thisWindow->wUsed = 0;
  1526.     }
  1527.  
  1528. void Show(short iNum)
  1529.     {
  1530.     register TEasyWindow *thisWindow;
  1531.  
  1532.     thisWindow = GoodWNum(iNum);
  1533.     if(thisWindow)
  1534.         {
  1535.         if(!((WindowPeek)(thisWindow->wWindow))->visible)    /* If so, just show it, and bring it to the front. */
  1536.             ShowWindow(thisWindow->wWindow);
  1537.         SelectWindow(thisWindow->wWindow);
  1538.         }
  1539.     }
  1540.  
  1541. void Hide(short iNum)
  1542. /*
  1543.   * Just do HideWindow to the
  1544.   * specified window number.
  1545.   */
  1546.     {
  1547.     register TEasyWindow *thisWindow;
  1548.  
  1549.     gCoolDragState = 0;                                    /* It might have been this window */
  1550.  
  1551.     thisWindow = GoodWNum(iNum);
  1552.     if(thisWindow)
  1553.         HideWindow(thisWindow->wWindow);
  1554.     }
  1555.  
  1556.     
  1557.  
  1558. void GetWindowRect(short n,Rect *r)
  1559. /*
  1560.   * return the window's current rectangle
  1561.   * in global coördinate space.
  1562.   */
  1563.     {
  1564.     TEasyWindow *thisWindow;
  1565.     WindowPtr g;
  1566.  
  1567.     if(!(thisWindow = GoodWNum(n)))
  1568.         return;
  1569.  
  1570.     if(thisWindow->wUsed)
  1571.         {
  1572.         g = thisWindow->wWindow;
  1573.         SetPort(g);
  1574.         *r = g->portRect;
  1575.         LocalToGlobal((Point *)r);
  1576.         LocalToGlobal((Point *)( (char*)r + 4));
  1577.         }
  1578.     }
  1579.         
  1580. WindowPtr GetWindowPtr(short n)
  1581. /*
  1582.   * return the windowptr for
  1583.   * the specified window number
  1584.   */
  1585.     {
  1586.     TEasyWindow *thisWindow;
  1587.     WindowPtr g;
  1588.  
  1589.     if(!(thisWindow = GoodWNum(n)))
  1590.         g = 0;
  1591.     else
  1592.         g = thisWindow->wWindow;
  1593.  
  1594.     return g;
  1595.     }
  1596.  
  1597. Boolean GetWindowVisible(short n)
  1598. /*
  1599.   * return true if the window exists,
  1600.   * and is visible, or false if its invisible
  1601.   * or doesn't exist.
  1602.   */
  1603.     {
  1604.     register WindowPtr g;
  1605.  
  1606.     g = GetWindowPtr(n);
  1607.     if(g)
  1608.         return ((WindowPeek)g)->visible;
  1609.     else
  1610.         return false;
  1611.     }
  1612.  
  1613. void SaveWindowPosition(short n)
  1614. /*
  1615.   * Save the position of window number n,
  1616.   * or all windows if n = -1;
  1617.   */
  1618.     {
  1619.     Rect **rH;
  1620.     register Rect *r;
  1621.     register short i;
  1622.     register short n1,n2;
  1623.     TEasyWindow *thisWindow;
  1624.  
  1625.     rH = (Rect **)NewHandleClear(sizeof(Rect));
  1626.     FailNil((long)rH);
  1627.     HLock((Handle)rH);
  1628.     r = *rH;
  1629.  
  1630.     if(n < 0)
  1631.         {
  1632.         n1 = 0;
  1633.         n2 = gEasyWindowListSize-1;
  1634.         }
  1635.     else
  1636.         n1 = n2 = n;
  1637.  
  1638.     for(i = n1; i<=n2; i++)
  1639.         {
  1640.         thisWindow = GoodWNum(i);
  1641.         if(thisWindow && thisWindow->wUsed)
  1642.             {
  1643.             GetWindowRect(i,r);
  1644.             if( !((WindowPeek)(thisWindow->wWindow))->visible )
  1645.                 SwapShort(r->left,r->right);
  1646.             Replace1Resource((Handle)rH,kWinPosType,i);
  1647.             }
  1648.         }
  1649.  
  1650.     DisposHandle( (Handle)rH );
  1651.     }
  1652.  
  1653. void ForgetWindowPosition(short n)
  1654. /*
  1655.   * Forget the saved window position n,
  1656.   * or all windows if n<0.
  1657.   */
  1658.     {
  1659.     register short i;
  1660.     register short n1,n2;
  1661.     register TEasyWindow *thisWindow;
  1662.  
  1663.     if(n < 0)
  1664.         {
  1665.         n1 = 0;
  1666.         n2 = gEasyWindowListSize-1;
  1667.         }
  1668.     else
  1669.         n1 = n2 = n;
  1670.  
  1671.     for(i = n1; i<=n2; i++)
  1672.         {
  1673.         thisWindow = GoodWNum(i);
  1674.         if(thisWindow && thisWindow->wUsed)
  1675.             Replace1Resource(0,kWinPosType,i);
  1676.         }
  1677.     }
  1678.  
  1679.  
  1680. void Replace1Resource(Handle h,long type,short id)
  1681. /*
  1682.   * This is AddResource with a
  1683.   * RmveResource if necessary.
  1684.   * Pass h==nil to delete the resource.
  1685.   */
  1686.     {
  1687.     Handle old;
  1688.  
  1689.     /*
  1690.      * A lame hack to prevent writing resources
  1691.      * to a lightspeed project file.
  1692.      */
  1693.     if( *(StringPtr)(0x910 + (*(StringPtr)0x910)) == 'π')
  1694.         {
  1695.         /* do nothing */
  1696.         }
  1697.     else
  1698.         {
  1699.  
  1700.         old = Get1Resource(type,id);
  1701.         if(old)
  1702.             RemoveResource(old);
  1703.         if(h)
  1704.             {
  1705.             AddResource(h,type,id,(StringPtr)"\p");
  1706.             WriteResource(h);
  1707.             DetachResource(h);
  1708.             }
  1709.  
  1710.         }
  1711.     }
  1712.  
  1713. void CheckMenubar(void)
  1714.     {
  1715.     if(gInvalidMenuBar)
  1716.         {
  1717.         DrawMenuBar();
  1718.         gInvalidMenuBar = false;
  1719.         }
  1720.     }
  1721.  
  1722. /*----------------
  1723.     Event Routines
  1724. ----------------*/
  1725.  
  1726. Boolean HandleUpdateEvent(EventRecord *er)
  1727. /*
  1728.  * Update the appropriate window, if we know who it is.
  1729.  */
  1730.     {
  1731.     Boolean result;
  1732.     short wNum;
  1733.     TEasyWindow *thisEasyWindow;
  1734.     WindowPtr w;
  1735.     GrafPtr oldPort;
  1736.  
  1737.     GetPort(&oldPort);
  1738.     result = false;
  1739.  
  1740.     if(er->what != updateEvt)
  1741.         {
  1742.         result = false;
  1743.         goto goHome;
  1744.         }
  1745.  
  1746.     w = (WindowPtr)er->message;
  1747.     wNum = ScanWindowList(w);                    /* other than null or click, scan list        */
  1748.     thisEasyWindow = GoodWNum(wNum);            /* and get record                    */
  1749.  
  1750.     if(thisEasyWindow)
  1751.         {
  1752.         Rect visBounds;
  1753.         beUpdateProcPtr fp;
  1754.  
  1755.         SetPort(w);
  1756.         BeginUpdate(w);
  1757.     
  1758.         result = true;
  1759.         visBounds = (**w->visRgn).rgnBBox;
  1760.         fp = thisEasyWindow->wUpdateProc;
  1761.         if(fp)
  1762.             {
  1763.             SetPort(thisEasyWindow->wWindow);                    /* Set port to window    */
  1764.             (*fp)(wNum);            /* Call drawing proc        */
  1765.             }
  1766.  
  1767.         SetOrigin(0,0);
  1768.  
  1769.         if (thisEasyWindow->flags & wGrowable)            /* Draw growbox, if...    */
  1770.             MyDrawGrowIcon(w);
  1771.  
  1772.         ClipRect(&gBigRect);
  1773.  
  1774.  
  1775.         DrawControls(w);
  1776.         EndUpdate(w);
  1777.         }
  1778.     else
  1779.         result = false;
  1780.  
  1781. goHome:
  1782.  
  1783.     SetPort(oldPort);
  1784.     return result;
  1785.     }
  1786.  
  1787.  
  1788. Boolean ActivateWindow(WindowPtr w, Boolean activate)
  1789.     {
  1790.     Boolean result;
  1791.     short wNum;
  1792.     TEasyWindow *thisEasyWindow;
  1793.     GrafPtr oldPort;
  1794.  
  1795.     GetPort(&oldPort);
  1796.  
  1797.     wNum = ScanWindowList(w);                    /* other than null or click, scan list        */
  1798.     thisEasyWindow = GoodWNum(wNum);            /* and get record                    */
  1799.  
  1800.     if(!thisEasyWindow)
  1801.         {
  1802.         result = false;
  1803.         goto goHome;
  1804.         }
  1805.  
  1806.     result = true;
  1807.  
  1808.     FrontDAEdits();
  1809.  
  1810.     if(thisEasyWindow)
  1811.         {
  1812.         SetPort(thisEasyWindow->wWindow);
  1813.         if(activate)
  1814.             {
  1815.             beActivateProcPtr fp;
  1816.             short copyItem,printItems;
  1817.  
  1818.             if(thisEasyWindow->flags & wCopyDraw)
  1819.                 copyItem = 1;
  1820.             else
  1821.                 copyItem = -1;
  1822.  
  1823.             EnDisEdits(-1,-1,copyItem,-1,-1);
  1824.  
  1825.             if(((thisEasyWindow->flags & wPrintDraw) && gHasGX)
  1826.                     || (gAppPageSetupProc && gAppPrintProc) )
  1827.                 printItems = 1;
  1828.             else
  1829.                 printItems = -1;
  1830.             SetMenuItem(mPageSetup,printItems,0,0,nil);
  1831.             SetMenuItem(mPrint,printItems,0,0,nil);
  1832.  
  1833.             fp = thisEasyWindow->wActivateProc;
  1834.             if(fp)
  1835.                 (*fp)(wNum);
  1836.             }
  1837.         else
  1838.             {
  1839.             beDeactivateProcPtr fp;
  1840.                         
  1841.             EnDisEdits(-1,-1,-1,-1,-1);
  1842.             SetMenuItem(mPageSetup,-1,0,0,nil);
  1843.             SetMenuItem(mPrint,-1,0,0,nil);
  1844.             fp = thisEasyWindow->wDeactivateProc;
  1845.             if(fp)
  1846.                 (*fp)(wNum);
  1847.             }
  1848.  
  1849.         InitCursor();
  1850.         if (thisEasyWindow->flags & wGrowable)            /* Draw growbox, if...    */
  1851.             MyDrawGrowIcon(w);
  1852.         }
  1853.  
  1854. goHome:
  1855.     SetPort(oldPort);
  1856.     return result;
  1857.     }
  1858.  
  1859. Boolean HandleActivateEvent(EventRecord *er)
  1860. /*
  1861.  * Handle it, if we can find out who it is.
  1862.  */
  1863.     {
  1864.     Boolean result;
  1865.  
  1866.     result = true;
  1867.  
  1868.     switch(er->what)
  1869.         {
  1870.         case activateEvt:
  1871.             ActivateWindow((WindowPtr)er->message,er->modifiers & 1);
  1872.             break;        
  1873.  
  1874.         case kOSEvent:
  1875.             switch ((unsigned long) er->message >> 24)    /*  high byte of message  */
  1876.                 {
  1877.                  case kSuspendResumeMessage:
  1878.                     ActivateWindow(FrontWindow(),er->modifiers & 1);
  1879.                     break;
  1880.                 default:
  1881.                     result = false;
  1882.                     break;
  1883.                 }
  1884.             break;
  1885.  
  1886.         default:
  1887.             result = false;
  1888.             break;
  1889.         }
  1890. goHome:
  1891.     return result;
  1892.     }
  1893.  
  1894.  
  1895.  
  1896.  
  1897.  
  1898. void EventLoop(void)
  1899.     {
  1900.     EventRecord er;
  1901.     short i;
  1902.     register short wNum;
  1903.     WindowPtr w;
  1904.     register TEasyWindow *thisEasyWindow;
  1905.     Boolean tookKey,tookEvent;
  1906.  
  1907.     CheckMenubar();
  1908.  
  1909.     WaitNextEvent(0xffff,&er,gSleep,nil);
  1910.         {
  1911.         gLastModifiers = er.modifiers;
  1912.         gLastEventTime = er.when;
  1913.  
  1914.         if(er.what > 5 && er.what < 12)                    /* update event or higher: in message    */
  1915.             w = (WindowPtr)er.message;
  1916.         else
  1917.             w = FrontWindow();                            /* else, use FrontW                    */
  1918.  
  1919.         if(er.what > 1)
  1920.             {
  1921.             wNum = ScanWindowList(w);                    /* other than null or click, scan list        */
  1922.             thisEasyWindow = GoodWNum(wNum);            /* and get record                    */
  1923.             }
  1924.         else
  1925.             thisEasyWindow = 0;
  1926.  
  1927.         SetPort(w);
  1928.  
  1929.         if(thisEasyWindow && thisEasyWindow->wEventProc)
  1930.             (*thisEasyWindow->wEventProc)(wNum,&er,&tookEvent);
  1931.         else
  1932.             tookEvent = 0;
  1933.  
  1934.         if(!tookEvent)
  1935.             switch (er.what)
  1936.                 {
  1937.                 case 0:    /* null event */
  1938.                     break;
  1939.     
  1940.                 case mouseDown:
  1941.                     FrontDAEdits();
  1942.                     DoMouseClick(&er);
  1943.                     break;
  1944.     
  1945.                 case keyDown:
  1946.                 case autoKey:
  1947.                     FrontDAEdits();
  1948.     
  1949.                     tookKey = false;
  1950.                     if( (!gMenuNeedsCmdKey) || (er.modifiers & 256) )
  1951.                         tookKey = DoKeyPress(er.message);
  1952.     
  1953.                     if(!tookKey && ((!gMenuNeedsCmdKey) || (er.modifiers & 256)) )
  1954.                         tookKey = CoolBigEasyCmdKeys(er.message & 0xFF);
  1955.     
  1956.                     if(!tookKey)
  1957.                         if(thisEasyWindow)
  1958.                             {
  1959.                             beKeyProcPtr fp;
  1960.                             
  1961.                             fp = thisEasyWindow->wKeyProc;
  1962.                             if(fp)
  1963.                                 {
  1964.                                 SetPort(thisEasyWindow->wWindow);                /* Set port to window    */
  1965.                                 (*fp)(wNum,            /* Call key proc        */
  1966.                                         (short)(er.message&0xff),            /* with the key */
  1967.                                         (short)((er.message>>8)&0xff),        /* the key code */
  1968.                                         er.modifiers);                        /* and the modifiers */
  1969.                                 }
  1970.                             }
  1971.                     break;
  1972.     
  1973.                 case updateEvt:
  1974.                     HandleUpdateEvent(&er);
  1975.                     break;
  1976.     
  1977.                 case activateEvt:
  1978.                     HandleActivateEvent(&er);
  1979.                     break;
  1980.     
  1981.                 case kOSEvent:
  1982.                     switch ((unsigned long) er.message >> 24)    /*  high byte of message  */
  1983.                         {
  1984.                          case kSuspendResumeMessage:
  1985.                             if(thisEasyWindow)                    /* just like activate event... */
  1986.                                 {
  1987.                                 ActivateWindow(FrontWindow(),
  1988.                                         er.message & kResumeMask);
  1989.                                 }
  1990.                         break;
  1991.                         }
  1992.                     break;
  1993.     
  1994.                 case kHighLevelEvent:
  1995.                     AEProcessAppleEvent(&er);
  1996.                     break;
  1997.                 case diskEvt:
  1998.                     if (er.message & 0xffff0000) {
  1999.                         Point where = {100,100};
  2000.                     //    DIBadMount(where, er.message);
  2001.                     }
  2002.                     break;    
  2003.                 default:
  2004.                     /*Debugger();/**/
  2005.                     ;
  2006.                 }
  2007.         }
  2008.  
  2009.     /*
  2010.       * See if we're doing a fake cool drag-window
  2011.       */
  2012.     if(gCoolDragState)
  2013.         {
  2014.         Point p,q;
  2015.  
  2016.         SetPort(gCoolDragEW->wWindow);
  2017.         GetMouse(&p);
  2018.         LocalToGlobal(&p);
  2019.         if( (p.v!=gCoolDragPoint.v) || (p.h!=gCoolDragPoint.h) )
  2020.             {
  2021.             q.h = gCoolDragEW->wWindow->portRect.left;
  2022.             q.v = gCoolDragEW->wWindow->portRect.top;
  2023.             LocalToGlobal(&q);
  2024.             MoveWindow(gCoolDragEW->wWindow,
  2025.                     q.h+p.h-gCoolDragPoint.h,
  2026.                     q.v+p.v-gCoolDragPoint.v,0);
  2027.             gCoolDragPoint = p;
  2028.  
  2029.                 {
  2030.                 beMoveWindowProcPtr fp;
  2031.  
  2032.                 fp = gCoolDragEW->wMoveWindowProc;
  2033.                 if(fp)
  2034.                     (fp)(gCoolDragWindowNumber);                    
  2035.                 }
  2036.  
  2037.             }
  2038.         if(!Button())
  2039.             gCoolDragState = 0;
  2040.         }
  2041.  
  2042.     SystemTask();
  2043.     w = FrontWindow();
  2044.     if ( w == gLastFrontIdle)                    /* Minor optimization, wins if the same        */
  2045.         wNum = gLastFrontWindowNumber;        /* window is frontmost for a while.            */
  2046.     else
  2047.         {
  2048.         wNum = ScanWindowList(w);
  2049.         gLastFrontIdle = w;
  2050.         gLastFrontWindowNumber = wNum;
  2051.         }
  2052.  
  2053.     if(er.what != mouseDown && er.what != activateEvt && !gQuitApp)    /* anything but a mousedown or [de]activate */
  2054.         {
  2055.         gIdleSeed ++;
  2056.         if(gIdleSeed & 1)    /* every other chance... */
  2057.             for(i = 1; i<gEasyWindowListSize; i++)
  2058.                 {
  2059.                 if(gEasyWindowList[i].wUsed && gEasyWindowList[i].wIdleProc)
  2060.                     {
  2061.                     SetPort(gEasyWindowList[i].wWindow);
  2062.                     (*gEasyWindowList[i].wIdleProc)
  2063.                             ((short)i,(Boolean)(w == gEasyWindowList[i].wWindow));
  2064.                     }
  2065.                 }
  2066.         }
  2067.  
  2068.     if (gMasterIdleProc && !gQuitApp)
  2069.         (*gMasterIdleProc)();
  2070.     }
  2071.  
  2072.  
  2073. Boolean CoolBigEasyCmdKeys(short key)
  2074.     {
  2075.     WindowRecord *w;
  2076.  
  2077.     switch(key)
  2078.         {
  2079.         /*
  2080.          * Rotate active window
  2081.          */
  2082.         case 9:        /* <tab> */
  2083.             w = *(WindowRecord **)0x9D6;        /* windowlist */
  2084.             if(w)
  2085.                 {
  2086.                 while (w->nextWindow)
  2087.                     w = w->nextWindow;
  2088.                 SelectWindow((WindowPtr)w);
  2089.                 }
  2090.             break;
  2091.  
  2092.         default:
  2093.             return false;
  2094.         }
  2095.     return true;
  2096.     }
  2097.  
  2098.  
  2099. void IdleWindow(short n)
  2100. /*
  2101.  * Idle window number n, or
  2102.  * -1 to idle all windows.
  2103.  */    
  2104.     {
  2105.     register short i;
  2106.     short lo,hi;
  2107.     WindowPtr w;
  2108.     register TEasyWindow *ew;
  2109.     GrafPtr oldPort;
  2110.  
  2111.     GetPort(&oldPort);
  2112.  
  2113.     if(n<0)
  2114.         {
  2115.         lo = 1;
  2116.         hi = gEasyWindowListSize;
  2117.         }
  2118.     else
  2119.         {
  2120.         lo = n;
  2121.         hi = n + 1;
  2122.         }
  2123.  
  2124.     w = FrontWindow();
  2125.     ew = &gEasyWindowList[lo];
  2126.  
  2127.     for(i = lo; i < hi; i++)
  2128.         {
  2129.         if(ew->wUsed && ew->wIdleProc)
  2130.             {
  2131.             SetPort(ew->wWindow);
  2132.             (*ew->wIdleProc)((short)i,ew->wWindow == w);
  2133.             }
  2134.         ew++;
  2135.         }
  2136.  
  2137.     SetPort(oldPort);
  2138.     SystemTask();
  2139.     }    
  2140.  
  2141. void MyDrawGrowIcon(WindowPtr w)
  2142.     {
  2143.     Rect r;
  2144.  
  2145.     SetPort(w);
  2146.     GetGrowRect(w,&r);
  2147.     ClipRect(&r);
  2148.     DrawGrowIcon(w);
  2149.     ClipRect(&gBigRect);
  2150.     }
  2151.  
  2152.  
  2153. void SetMasterOpenAppProc(beOpenAppProcPtr openAppProc)
  2154.     {
  2155.     gMasterOpenAppProc = openAppProc;
  2156.     if(gHasAppleEvents)
  2157.         AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
  2158.                 (AEEventHandlerUPP)BigEasyOpenAppThang, 0, false);
  2159.     }
  2160.  
  2161.  
  2162. void SetMasterOpenDocProc(beOpenDocProcPtr openDocProc)
  2163.     {
  2164.     gMasterOpenDocProc = openDocProc;
  2165.     if(gHasAppleEvents)
  2166.         AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
  2167.                 (AEEventHandlerUPP)BigEasyOpenDocThang, 0, false);
  2168.     }
  2169.  
  2170. void SetMasterQuitAppProc(beQuitAppProcPtr quitAppProc)
  2171.     {
  2172.     gMasterQuitAppProc = quitAppProc;
  2173.     }
  2174.  
  2175. pascal OSErr BigEasyOpenAppThang(AppleEvent *theEvent, AppleEvent *reply,long refCon)
  2176.     {
  2177.     #pragma unused (reply,refCon,theEvent)
  2178.     return noErr;
  2179.     }
  2180.  
  2181. pascal OSErr BigEasyOpenDocThang(AppleEvent *message, AppleEvent *reply,long refCon)
  2182.     {
  2183.     FSSpec fSpec;
  2184.     AEDescList docList;
  2185.     long index, itemsInList;
  2186.     Size actualSize;
  2187.     AEKeyword keywd;
  2188.     DescType typeCode;
  2189.     OSErr thisError;
  2190.     #pragma unused (reply,refCon)
  2191.  
  2192.     thisError = AEGetParamDesc(message, keyDirectObject, typeAEList, &docList);
  2193.     if(thisError)
  2194.         goto goHome;
  2195.  
  2196.     thisError = MissedAEParameters(message);
  2197.     if(thisError)
  2198.         goto goHome;
  2199.  
  2200.     thisError = AECountItems(&docList, &itemsInList);
  2201.     if(thisError)
  2202.         goto goHome;
  2203.  
  2204.     for (index = 1; index <= itemsInList; index++)
  2205.         {
  2206.         thisError = AEGetNthPtr(&docList, index, typeFSS, &keywd, &typeCode,
  2207.                     (Ptr)&fSpec, sizeof(FSSpec), &actualSize);
  2208.         if(thisError)
  2209.             goto goHome;
  2210.  
  2211.         if(gMasterOpenDocProc)
  2212.             (*gMasterOpenDocProc)(&fSpec);
  2213.         }
  2214.  
  2215.     thisError = AEDisposeDesc(&docList);
  2216.  
  2217. goHome:
  2218.     return thisError;
  2219.     }
  2220.  
  2221. pascal OSErr BigEasyQuitAppThang(AppleEvent *theEvent, AppleEvent *reply,long refCon)
  2222.     {
  2223.     OSErr thisError;
  2224.     #pragma unused (reply,refCon)
  2225.  
  2226.     thisError = MissedAEParameters(theEvent);
  2227.     if (!thisError)
  2228.         {
  2229.         ++ gQuitApp;
  2230.     
  2231.         if(gMasterQuitAppProc)
  2232.             (*gMasterQuitAppProc)();
  2233.         }
  2234.  
  2235.     return thisError;
  2236.     }
  2237.  
  2238. OSErr MissedAEParameters (AppleEvent *message)
  2239.     {
  2240.     DescType typeCode;
  2241.     Size actualSize;
  2242.     OSErr err;
  2243.  
  2244.     err = AEGetAttributePtr(message, keyMissedKeywordAttr, typeWildCard,
  2245.             &typeCode, nil, 0L, &actualSize);
  2246.     if (err == errAEDescNotFound)
  2247.         return(noErr);
  2248.     return(err = noErr ? errAEEventNotHandled : err);
  2249.     }
  2250.  
  2251.  
  2252.  
  2253.  
  2254. void InitBigEasy(void)
  2255.     {
  2256.     long result;
  2257.  
  2258.     InstallMyExitToShell();
  2259.     gMasterOpenAppProc = nil;
  2260.     gMasterOpenDocProc = nil;
  2261.     gMasterIdleProc = nil;
  2262.     gAboutProc = nil;
  2263.     gQuitApp = false;
  2264.     gMenuNeedsCmdKey = true;
  2265.     gStaggerWindows = true;
  2266.     gWindowsInView = true;
  2267.     gSleep = 0;
  2268.     gInvalidMenuBar = false;
  2269.  
  2270.     gStagStepX = 7;
  2271.     gStagStepY = 7;
  2272.  
  2273.     SetRect(&gBigRect,-16000,-16000,16000,16000);
  2274.  
  2275.     gEasyWindowListH = (TEasyWindow**)NewHandleClear(sizeof(TEasyWindow));
  2276.     HLock((Handle)gEasyWindowListH);
  2277.     gEasyWindowList = *gEasyWindowListH;
  2278.     gEasyWindowList[0].wUsed = 0;
  2279.     gEasyWindowListSize = 1;
  2280.  
  2281.     gLastFrontIdle = (WindowPtr) 0;
  2282.     gLastFrontWindowNumber = -1;
  2283.  
  2284.     gCoolDragState = 0;
  2285.  
  2286.  
  2287. /*
  2288.  * 7.0 Feature stuff
  2289.  */
  2290.     gSystemVersion = (Gestalt('sysv', &result)) ? 0 : result;
  2291.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &result) ? false : result != 0);
  2292.     gHasColor = (Gestalt('qdrw',&result)) ?
  2293.             false : (result & (1<<gestaltHasDeepGWorlds)) != 0;
  2294.  
  2295.     /*
  2296.      * The quit-app message, if available.
  2297.      */
  2298.     gMasterQuitAppProc = nil;
  2299.     if(gHasAppleEvents)
  2300.         AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
  2301.                 (AEEventHandlerUPP)BigEasyQuitAppThang, 0, false);
  2302.  
  2303. /*
  2304.  * GX Feature stuff
  2305.  */
  2306.  
  2307. #ifdef BigEasyGXPrinting
  2308.     gHasGX = WantsGX
  2309.             && ( (Gestalt(gestaltGXVersion,&result)) ? false : true );
  2310.  
  2311.     if(gHasGX)
  2312.         {
  2313.         GXEnterGraphics();
  2314.         GXInitPrinting();
  2315.         }
  2316. #else
  2317.     gHasGX = false;
  2318. #endif
  2319.  
  2320.  
  2321.     }
  2322.  
  2323. static void ExitBigEasy(void)
  2324.     {
  2325. #ifdef BigEasyGXPrinting
  2326.     if(gHasGX)
  2327.         {
  2328.         GXExitGraphics();
  2329.         GXExitPrinting();
  2330.         }
  2331. #endif
  2332.     }
  2333.  
  2334. void main(void)
  2335.     {
  2336. #if 0
  2337. #ifdef THINK_C_PROFILE
  2338.     freopen("profile output","w+",stdout);
  2339.  
  2340.     InitProfile(1000,50);
  2341. #endif THINK_C_PROFILE    
  2342. #endif
  2343.  
  2344.     MaxApplZone();
  2345.     MoreMasters();
  2346.     MoreMasters();
  2347.  
  2348.     InitToolbox();
  2349.     StartMenus();
  2350.  
  2351.     InitBigEasy();
  2352.     Bootstrap();
  2353.     
  2354.     #if THINK_C >= 5
  2355.         #if defined(STACK_KILLER) || defined(TIMING_PROFILE)
  2356.             prepStackKiller();        /** slime from HELL **/
  2357.             #ifdef TIMING_PROFILE
  2358.                 InitTimingProfile(150);    /* call depth */
  2359.             #endif TIMING_PROFILE
  2360.         #endif
  2361.     #endif
  2362.  
  2363.     while (!gQuitApp)
  2364.         EventLoop();
  2365.  
  2366.     FlushEvents(0xffff,0);
  2367.  
  2368.     #ifdef TIMING_PROFILE
  2369.         DumpProfile(0, 0, "\ptiming stats");
  2370.     #endif
  2371.  
  2372.     ExitBigEasy();
  2373.  
  2374.     ExitToShell();
  2375.     }
  2376.  
  2377.